<?php
/**
 * Created by PhpStorm.
 * User: hebidu
 * Date: 15/12/3
 * Time: 18:01
 */
namespace app\index\domain;

use app\index\model\ErrorCode;
use app\utils\CryptUtils;
use think\Response;


class BaseDomain {

    protected $notify_id;
    protected $client_id;
    protected $time;
    //服务端允许的默认api版本
    protected $api_ver       = 100;
    protected $allowType     = ["json", "rss", "html"];
    protected $business_code = '';
    protected $cur_api_ver;  //服务端当前api_ver
    protected $domain_class;
    public function __construct(){
        G('begin');
        $this->notify_id     = isset($_POST['notify_id'])?$_POST['notify_id']:$this->apiReturnErr('缺少notify_id',ErrorCode::Lack_Parameter);
        $this->time  = isset($_POST['time'])?$_POST['time']:$this->apiReturnErr('缺少time',ErrorCode::Lack_Parameter);
        $this->client_id     = isset($_POST['client_id'])?$_POST['client_id']:$this->apiReturnErr('缺少client_id',ErrorCode::Lack_Parameter);
        $this->client_secret = isset($_POST['client_secret'])?$_POST['client_secret']:$this->apiReturnErr('缺少client_secret',ErrorCode::Lack_Parameter);
        $this->domain_class  = isset($_POST['domain_class'])?$_POST['domain_class']:$this->apiReturnErr('缺少domain_class',ErrorCode::Lack_Parameter);
        $this->request_api_ver = isset($_POST['api_ver'])?$_POST['api_ver']:$this->apiReturnErr('缺少api_ver',ErrorCode::Lack_Parameter);
        // $this->cur_api_ver   = C('api_ver')?intval(C('api_ver')):100;
        // $this->checkVersion($this->cur_api_ver);
    }
    /**
     * 缓存 api结果 并返回
     * @param  [type]  $key       [description]
     * @param  [type]  $data      [description]
     * @param  integer $time      [description]
     * @param  boolean $returnSuc [是否返回成功,否则不操作]
     * @return [type]             [null]
     */
    protected function cache($key,$data,$time=300,$returnSuc=true){
        S($key,json_encode($data),$time);
        if($returnSuc) $this->apiReturnSuc($data);
    }

    /**
     * 获取缓存
     * @param  [type]  $key     [description]
     * @param  integer $fresh   [description]
     * @param  integer $page    [当前页]
     * @param  integer $maxpage [最大缓存页]
     * @return [type]           [null]
     */
    protected function checkCache($key,$page=false,$maxpage=false,$fresh=false){
        $cache = S($key);
        if(false==$fresh && $page && $maxpage && $page<=$maxpage && $cache){
            $this->apiReturnSuc(json_decode($cache,true),true);
        }
    }

    /**
     * 服务端允许的api版本/列表
     * @param  [int|array]     $version
     * @return [type]          [description]
     */
    protected function checkVersion($version=''){
        if(!$version) $version = $this -> api_ver;
        if(is_array($version)){
            $legal = false;
            foreach($version as $item){
                if($item == intval($this->request_api_ver)){
                    $legal = true;
                    break;
                }
            }

            if($legal == false){
                $msg = "请更新客户端接口";
                $this->apiReturnErr($msg,ErrorCode::Api_Need_Update);
            }

        }else{

            if($version != $this->request_api_ver){
                $msg = "请更新客户端接口,最新版本:".$version;
                $this->apiReturnErr($msg,ErrorCode::Api_Need_Update);
            }
        }

    }

    /**
     * Ajax方式返回数据到客户端
     * @access protected
     * @param mixed $data 要返回的数据
     * @param String $type AJAX返回数据格式
     * @param int $json_option 传递给json_encode的option参数
     * @return void
     */
    protected function ajaxReturn($data) {
        //接口         $this->domain_class
        //创建时间     START_TIME
        //请求开始时间 app_send APP传过来
        //网络传输时间 START_TIME - app_send
        //接口执行耗时 G('begin','end',4).'s'
        //param
        //内存占用     G('begin','end','m').'kb';
        //请求头       $_SERVER['HTTP_USER_AGENT']

        $api_end  = microtime(true);
        $app_time = $this->time;

        $cache = (isset($data['cache']) && $data['cache']) ? 1: 0;
        $map = [
         'api_uri'      =>$this->domain_class,
         'create_time'  =>START_TIME,
         'start_time'   =>$app_time,
         'request_time' =>((float)START_TIME - (float)$app_time),
         'cost_time'    =>(float)($api_end - START_TIME),
         'params'       =>'cache:'.$cache.';吞吐量:'.\think\Debug::getThroughputRate().';内存占用:'.G('begin','end','m').';HTTP代理:'.$_SERVER['HTTP_USER_AGENT'].';',
        ];
        $model = M('apiHistory');
        if(false === $model ->add($map) && is_array($data)){
            $data['code'] = -1;
            $data['data'] = $model->getDbError();
        };

        $code = $data['code'];
        if($code == 0){
            $type = "T";
        }else{
            $type = "F";
        }

        $data = CryptUtils::encrypt($data);
        $now  = time();

        $param = array(
            'client_secret' =>$this->client_secret,
            'data'          =>$data,
            'notify_id'     =>$this->notify_id,
            'time'          =>strval($now),
            'type'          =>$type,
            'alg'           =>'md5',
        );

        $param['sign'] = CryptUtils::sign($param);
        Response::isExit(true);
        // sleep(3);
        Response::send($param,"json",false);


    }

    /**
     * ajax返回
     * @param $data
     * @internal param $i
     */
    protected function apiReturnSuc($data,$cache=false){
        addLog($this->domain_class,$this->api_ver,$data,'返回成功',true);
        $this->ajaxReturn(['code'=>0,'data'=>$data,'notify_id'=>$this->notify_id,'cache'=>$cache]);
    }

    /**
     * ajax返回，并自动写入token返回
     * @param $data
     * @param int $code
     * @internal param $i
     */
    protected function apiReturnErr($data,$code=-1){
        addLog($this->domain_class,$code,$data,'返回错误');
        $this->ajaxReturn(['code'=>$code,'data'=>$data,'notify_id'=>$this->notify_id,'cache'=>false]);
    }

    /**
     * @param $key
     * @param string $default
     * @param string $emptyErrMsg  为空时的报错
     * @return mixed
     */
    public function _post($key,$default='',$emptyErrMsg=''){
        $value = I("post._data_".$key,$default);

        if($default == $value && !empty($emptyErrMsg)){
            $this->apiReturnErr($emptyErrMsg,ErrorCode::Lack_Parameter);
        }

        $value = $this->escapeEmoji($value);

        if($default == $value && !empty($emptyErrMsg)){
            $this->apiReturnErr($emptyErrMsg,ErrorCode::Lack_Parameter);
        }
        return $value;
    }

    /**
     * @param $key
     * @param string $default
     * @param string $emptyErrMsg  为空时的报错
     * @return mixed
     */
    public function _get($key,$default='',$emptyErrMsg=''){
        $value = I("get.".$key,$default);

        if($default == $value && !empty($emptyErrMsg)){
            $this->apiReturnErr($emptyErrMsg,ErrorCode::Lack_Parameter);
        }
        return $value;
    }

    /**
     * TODO: 放到utils中，作为工具类
     * @brief 干掉emoji
     * @autho chenjinya@baidu.com
     * @param {String} $strText
     * @return {String} removeEmoji
     **/
    protected function escapeEmoji($strText,$bool = false) {
        $preg =  '/\\\ud([8-9a-f][0-9a-z]{2})/i';
        if ($bool == true) {
            $boolPregRes = (preg_match($preg,json_encode($strText,true)));
            return $boolPregRes;
        } else {
            $strPregRes = (preg_replace($preg,'',json_encode($strText,true)));
            $strRet = json_decode($strPregRes,true);
            if(strlen($strRet)==0){
                return "";
            }
            return $strRet;
        }
    }
}